﻿using Activity.Comm;
using Activity.Data;
using Activity.Helper;
using com.km.Cache;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Configuration;
using static Activity.Helper.OAuthHelper;

namespace Activity.API
{
    public class LotteryQueueHandler
    {
        /// <summary>
        /// 缓存KEY
        /// </summary>
        const string LotteryUserKey = "LotteryUser:";
        const string LotteryNumberKey = "LotteryUser:Number";
        /// <summary>
        /// 缓存超时5分钟
        /// </summary>
        const int TimeOut = 300000;
        /// <summary>
        /// 一次投资扣100分
        /// </summary>
        const int Integral = 100;
        /// <summary>
        /// 领取开始时间5.1活动
        /// </summary>
        static readonly DateTime beginDate51 = new DateTime(2018, 4, 27, 0, 0, 0);
        /// <summary>
        /// 领取结束时间5.1活动
        /// </summary>
        static readonly DateTime endDate51 = new DateTime(2018, 5, 1, 23, 59, 59);

        /// <summary>
        /// 领取开始时间夏季活动
        /// </summary>
        static readonly DateTime beginDateSummer = new DateTime(2018, 5, 2, 0, 0, 0);
        /// <summary>
        /// 领取结束时间夏季活动
        /// </summary>
        static readonly DateTime endDateSummer = new DateTime(2018, 7, 31, 23, 59, 59);

        /// <summary>
        /// 使用的Redis数据库索引
        /// </summary>
        public const int RedisDatabaseIndex = 4;
        /// <summary>
        /// 测试
        /// </summary>
        static readonly string isDebug = WebConfigurationManager.AppSettings["isDebug"];

        /// <summary>
        /// 认证微信
        /// </summary>
        /// <param name="openId"></param>
        /// <returns></returns>
        public Oauth2AccessToken GetOauth2AccessToken(string openId) {
            var accessToken = WeixinApi.GetOpenID(openId);
            return accessToken;
        }

        /// <summary>
        /// 中奖列表缓存
        /// </summary>
        /// <param name="list"></param>
        private void SetLoteryNumber(IList<LotteryNumber> list) {
            RedisCache.Max(LotteryNumberKey, list);
        }

        /// <summary>
        /// 同步抽奖次数
        /// </summary>
        /// <returns></returns>
        public IList<LotteryNumber> LotteryNumber {
            get {
                List<LotteryNumber> list = null;
                if (RedisCache.Exists(LotteryNumberKey))
                {
                    list = RedisCache.Get<List<LotteryNumber>>(LotteryNumberKey);
                }
                else
                {
                    using (var dc1 = new ActivityEntities())
                    {
                        list = dc1.t_Lottery2018Activity_log.Select(t => new LotteryNumber { Type = t.ActivityType, Index = t.LotteryType,OpenID = t.OpenID, CreateTime = t.LotteryTime }).ToList();
                    }
                    SetLoteryNumber(list);
                }
                return list;
            }
            
        }

        /// <summary>
        /// 抽奖
        /// </summary>
        /// <param name="type">类型:1－51劳动节抽奖(4.27-5.1);2－夏季抽奖(5.2-7.31)</param>
        /// <param name="openId"></param>
        /// <returns></returns>
        public Messages Lottery(int type, string openId)
        {
            if (string.IsNullOrWhiteSpace(openId))
                return new Messages() { IsSuc = false, Code = -1, Message = "无效的OPENID" };
            if (type != 1 || type != 2) new Messages() { IsSuc = false, Code = -1, Message = "无效类型" };
            //if (type == 1)
            //{
            //    if (DateTime.Now < beginDate51 && isDebug.ToLower() == "false")
            //    {
            //        return new Messages { IsSuc = false, Code = -1, Message = "亲，活动还没开始呢" };
            //    }

            //    if (DateTime.Now > endDate51 && isDebug.ToLower() == "false")
            //    {
            //        return new Messages { IsSuc = false, Code = -1, Message = "亲，活动已经结束了" };
            //    }
            //}

            //if (type == 2)
            //{
            //    if (DateTime.Now < beginDateSummer && isDebug.ToLower() == "false")
            //    {
            //        return new Messages { IsSuc = false, Code = -1, Message = "亲，活动还没开始呢" };
            //    }

            //    if (DateTime.Now > endDateSummer && isDebug.ToLower() == "false")
            //    {
            //        return new Messages { IsSuc = false, Code = -1, Message = "亲，活动已经结束了" };
            //    }
            //}

            var user = GetUser(openId);
            if (user.TotalIntegral < 100) return new Messages { IsSuc = false, Code = -1, Message = "积分不足" };
            var map = LoggeryInfo(type);
            var list = new List<double>(map.Values);
            var method = new AliasMethod(list);
            var index = method.Next();
            //检查ipad,iphone,果汁机数量
            if (index == 3 || index == 4)
            {
                if (CheckLotteryCount(type, index))
                {
                    //TODO:重新抽奖
                    index = method.Next();
                }
            }
            bool result = false;
            string jsonData = JsonHelper.ToJson(new LotteryMQItem { Index = index, Integral = Integral, OpenId = openId, Type = type });
            string data = Base64.Base64Encode(jsonData);
            //请求队列
            //string key = ConfigurationManager.AppSettings["PublishKey"];
            //string username = ConfigurationManager.AppSettings["UserName"];
            //string password = ConfigurationManager.AppSettings["PassWord"];
            //加密
            //var data_3ds = CryptData.Encrypt3DES(msg_body, key, out msg);

            dynamic obj = new { UserName = "", Password = "", Data = data };
            string host = ConfigurationManager.AppSettings["PublishHost"];
            var ss = HttpPost(host, obj);
            result = true;
            if (result)
            {
                var nums = LotteryNumber;
                nums.Add(new API.LotteryNumber { Type = type, Index = index, OpenID = openId, CreateTime = DateTime.Now });
                SetLoteryNumber(nums);
                //扣取积分
                user.TotalIntegral -= Integral;
                SetRedisUser(user);
                return new Messages { IsSuc = true, Code = 1, Message = index.ToString() };
            }
            return new Messages { IsSuc = false, Code = -1, Message = "数据异常" };
        }

        /// <summary>
        /// 检查抽奖次数
        /// </summary>
        /// <param name="type"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private bool CheckLotteryCount(int type, int index)
        {
            var dc = new ActivityEntities();
            var count = LotteryNumber.Where(c => c.Type == type && c.Index == index).Count();
            if (type == 1)
            {
                return count == 1;
            }

            if (type == 2)
            {
                switch (index)
                {
                    case 3:
                        return count >= 37;
                    case 4:
                        return count == 1;
                }
            }
            return false;
        }

        public string HttpPost(string url, object body)
        {
            string result = string.Empty;

            //创建HttpClient（注意传入HttpClientHandler）
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //string json = JsonConvert.SerializeObject(body);
            var response = client.PostAsJsonAsync(url, body).Result;
            if (response.IsSuccessStatusCode)
            {
                result = response.Content.ReadAsStringAsync().Result;
            }
            return result;
        }

        /// <summary>
        /// 生成奖项
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private Dictionary<string, double> LoggeryInfo(int type)
        {
            var map = new Dictionary<string, double>();
            if (type == 1)
            {
                map.Add("未中奖", 0.79499);
                map.Add("10元优惠券", 0.2);
                map.Add("斜挎包", 0.005);
                map.Add("IPad", 0.00001);
            }
            if (type == 2)
            {
                map.Add("未中奖", 0.69985);
                map.Add("10元优惠券", 0.2);
                map.Add("20元优惠券", 0.1);
                map.Add("活力果汁机", 0.0001);
                map.Add("iPhoneX", 0.00005);
            }
            return map;
        }

        /// <summary>
        /// 检查用户是否会员，成功返回用户积分
        /// </summary>
        /// <param name="openId"></param>
        /// <returns></returns>
        public LotteryUserInfo GetUser(string openId)
        {
            string key = LotteryUserKey + openId;
            LotteryUserInfo userInfo = null;
            if (RedisCache.Exists(key))
            {
                userInfo = RedisCache.Get<LotteryUserInfo>(key);
            }
            else {
                using (var dc = new HKERPEntities())
                {
                    userInfo = (from c in dc.KM_V_CardBinding
                                  join m in dc.CRM_Bas_CardInfo on c.CardID equals m.CardID
                                  where c.OpenID == openId
                                  select new LotteryUserInfo()
                                  {
                                      OpenID = c.OpenID,
                                      CardID = c.CardID,
                                      TotalIntegral = m.RemainIntegral
                                  }).FirstOrDefault();
                }
                SetRedisUser(userInfo);
            }
            return userInfo;
        }

        /// <summary>
        /// 中奖列表
        /// </summary>
        /// <param name="openId"></param>
        /// <param name="activityType">活动类型</param>
        /// <returns></returns>
        public IList<LotteryResult> List(string openId, int activityType)
        {
            var nums = LotteryNumber;
            IList<LotteryResult> result = nums.Where(c => c.OpenID == openId && c.Type == activityType).Select(c => new LotteryResult { ProductType = c.Index, CreateDate = c.CreateTime.Value }).ToList();
            return result;
        }

        /// <summary>
        /// 设置Redis
        /// </summary>
        /// <param name="userInfo"></param>
        private void SetRedisUser(LotteryUserInfo userInfo)
        {
            string key = LotteryUserKey + userInfo.OpenID;
            RedisCache.AddObject(key, userInfo, TimeOut);
        }
    }


    /// <summary>
    /// 队列抽奖对象
    /// </summary>
    [Serializable]
    public class LotteryMQItem
    {
        /// <summary>
        /// 微信编号 
        /// </summary>
        public string OpenId { get; set; }
        /// <summary>
        /// 类型
        /// </summary>
        public int Type { get; set; }
        /// <summary>
        /// 奖品编号
        /// </summary>
        public int Index { get; set; }
        /// <summary>
        /// 积分
        /// </summary>
        public int Integral { get; set; }
    }

    /// <summary>
    /// 抽奖次数
    /// </summary>
    [Serializable]
    public class LotteryNumber {
        public int Type { get; set; }
        public int Index { get; set; }
        public DateTime? CreateTime { get; set; }
        public string OpenID { get; set; }
    }
}
